Skip to content

使用 GPG 签名 commit 记录

  • GitHub 为了防止别人冒充你的身份,可以使用 GPG 签名 commit 记录。
  • 对于验证通过的 commit 提交记录 (具有可加密验证的 GPG、SSH、或 S/MIME 签名),GitHub 会打上「Verified/已验证」标签,确保代码提交者是可靠来源,增强代码安全性。
    • 对于大多数个人用户,GPG 或 SSH 会是对提交进行签名的最佳选择。
    • 在较大型组织的环境中通常需要 S/MIME 签名。
    • SSH 签名是最容易生成的。甚至可以将现有身份验证密钥上传到 GitHub 以用作签名密钥。
    • 生成 GPG 签名密钥比生成 SSH 密钥更复杂,但 GPG 具有 SSH 所没有的功能。GPG 密钥可以在不再使用时过期或撤销。GitHub 将已使用此类密钥进行签名的提交显示为“已验证”,除非密钥标记为已泄露。SSH 密钥没有此功能。

生成 GPG 密钥对

下载并安装 GPG

  • 手动下载: GPG 命令行工具

  • 包管理器:

    bash
    # windows
    scoop install gpg4win
    
    # mac/linux
    brew install gpg

一些 linux 发行版需要改用 gpg2。

bash
git config --global gpg.program gpg2

生成 GPG 密钥对(公钥/私钥)

bash
gpg --full-generate-key

该命令为交互式命令,需要根据提示选择算法类型,指定密钥的有效期,输入你的真实姓名和电子邮件,设置密码等。

  1. 密钥类型:选择使用的密钥类型,或按 Enter 键选择默认的 RSA 和 RSA。
  2. 椭圆曲线:按 Enter 键选择默认的椭圆曲线 Curve 25519
  3. 有效期限:按需指定密钥有效期,或按 Enter 键选择默认的永不过期
  4. 电子邮件地址:需为 GitHub 账户内配置的邮箱地址。
  5. 安全密码:设置密码,用于保护密钥。建议使用强密码。

列出已创建的 GPG 密钥

bash
# 列出所有 GPG 密钥
$ gpg --list-keys --keyid-format LONG

# 列出所有 GPG 私钥
$ gpg --list-secret-keys --keyid-format LONG

# 列出指定邮箱的 GPG 密钥
$ gpg --list-secret-keys --keyid-format LONG "your_email"

示例

bash
gpg --list-secret-keys --keyid-format LONG "example@example.com"
/Users/hubot/.gnupg/secring.gpg
------------------------------------
sec   4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
uid                          Hubot <example@example.com>
ssb   4096R/4BB6D45482678BE3 2016-03-10
  • 上面的例子中,GPG 密钥 ID 为 3AA5C34371567BD2

导出公钥

bash
gpg --armor --export <GPG 密钥 ID>

复制以 -----BEGIN PGP PUBLIC KEY BLOCK----- 开头并以 -----END PGP PUBLIC KEY BLOCK----- 结尾的 GPG 密钥。

示例

bash
gpg --armor --export 3AA5C34371567BD2
# Prints the GPG key ID, in ASCII armor format

添加 GPG 密钥到 GitHub

将电子邮件与 GPG 密钥关联

列出本地公钥和私钥

列出本地公钥和私钥的长形式 GPG 密钥。签名提交或标记需要私钥。

bash
$ gpg --list-secret-keys --keyid-format LONG
/Users/hubot/.gnupg/secring.gpg
------------------------------------
sec   4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
uid                          Hubot <hubot@example.com>
ssb   4096R/4BB6D45482678BE3 2016-03-10

# 在本例中,GPG 密钥 ID 为 3AA5C34371567BD2

注意

  • Linux 上的某些 GPG 安装可能需要改用 gpg2 --list-keys --keyid-format LONG 查看现有密钥的列表。
  • 在这种情况下,还需要通过运行 git config --global gpg.program gpg2 来配置 Git 以使用 gpg2

编辑 GPG 密钥

bash
$ gpg --edit-key <GPG key ID>
# eg: gpg --edit-key 3AA5C34371567BD2

# 进入编辑模式后,可以输入 help 查看帮助
# 添加用户
> adduid

# 按照提示提供您的真实姓名、电子邮件地址和任何注释。
# 可以通过选择 N、C 或 E 来修改条目。
# 要将电子邮件地址保密,请使用 GitHub 提供的 no-reply 电子邮件地址。
Real Name: OCTOCAT
Email address: "octocat@github.com"
Comment: GITHUB-KEY
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?

# 输入 O 以确认你的选择。
> O

# 输入密钥的密码

# 输入 save 以保存更改。
> save

然后使用 gpg --armor --export <GPG 密钥 ID> 导出公钥,添加到 GitHub。

与本地 Git 仓库关联

  1. 如果之前已将 Git 配置为在使用 --gpg-sign 签名时使用不同的密钥格式,请取消设置此配置,以便使用默认 openpgp 格式。

    bash
    git config --global --unset gpg.format
  2. 列出本地已创建的 GPG 密钥:

    bash
    gpg --list-secret-keys --keyid-format LONG "your_email"
  3. 从 GPG 密钥列表中复制您想要使用的 GPG 密钥 ID 的长形式:

    bash
    $ gpg --list-secret-keys --keyid-format=long
    /Users/hubot/.gnupg/secring.gpg
    ------------------------------------
    sec   4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
    uid                          Hubot <hubot@example.com>
    ssb   4096R/4BB6D45482678BE3 2016-03-10
    
    # 在本例中,GPG 密钥 ID 为 3AA5C34371567BD2
  4. 在本地 Git 仓库中配置该密钥,对 commit 提交进行签名:

    bash
    git config --global user.signingkey 3AA5C34371567BD2
  5. (可选)若要将 Git 配置为默认对所有提交进行签名:

    bash
    git config --global commit.gpgsign true

至此,你已经成功将创建的 GPG 密钥与本地 Git 仓库进行关联。在本地修改完代码后书写 Git commit message 时进行签名,以此验明提交者的真实性。

签名 Git commit

提示

要存储 GPG 密钥密码,以便无需在每次对提交签名时输入该密码,我们建议使用以下工具:

  • 对于 Mac 用户,GPG Suite 支持在 Mac OS 密钥链中存储 GPG 密钥密码。
  • 对于 Windows 用户,Gpg4win 将与其他 Windows 工具集成。

你也可以手动配置 gpg-agent 以保存 GPG 密钥密码,但这不会与 Mac OS 密钥链(如 ssh 代理)集成,并且需要更多设置。

运行 Git commit 命令时需要用到 -S 参数。

  1. 在本地完成代码编辑需要提交更改时,将 -S 参数添加到 git commit 命令中:

    bash
    git commit -S -m "your_commit_message"
  2. 如果不希望每次都要输入 -S 标志,你可以使用以下命令行设置 Git 自动为 commit 签名:

    bash
    git config --global commit.gpgsign true
  3. 如提示输入密码,则提供生成 GPG 密钥时设置的密码。

签名 Git tag

  1. 若要对标记进行签名,请将 -s 添加到 git tag 命令。

    bash
    $ git tag -s MYTAG
    # Creates a signed tag
  2. 通过运行 git tag -v [tag-name] 验证已签名的标记。

    bash
    $ git tag -v MYTAG
    # Verifies the signed tag

验证签名

将签了名的提交推送至 Github 代码仓库后,你可以在在代码仓库的「Commit 提交」tab 页查看提交验证是否签名成功。